/* Copyright (c) 2012 HyeonJe Jun (http://github.com/noraesae)
 * Licensed under the MIT License
 */
(function (factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS
        factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {
    'use strict';

    // The default settings for the plugin
    var defaultSettings = {
        wheelSpeed: 10,
        wheelPropagation: false,
        minScrollbarLength: null,
        useBothWheelAxes: false,
        useKeyboard: true,
        suppressScrollX: false,
        suppressScrollY: false,
        scrollXMarginOffset: 0,
        scrollYMarginOffset: 0,
        includePadding: false,
        isPopup: false, //created by Ankit
        isIframe: false, //created by Ankit
        slider:false, // created by Ankit
        an_MaxWidth:false // created by Ankit
    };

    var getEventClassName = (function () {
        var incrementingId = 0;
        return function () {
            var id = incrementingId;
            incrementingId += 1;
            return '.perfect-scrollbar-' + id;
        };
    }());

    $.fn.perfectScrollbar = function (suppliedSettings, option) {

        return this.each(function () {
            
            // Use the default settings
            var settings = $.extend(true, {}, defaultSettings),
            $this = $(this);

            if (typeof suppliedSettings === "object") {
                // But over-ride any supplied
                $.extend(true, settings, suppliedSettings);
            } else {
                // If no settings were supplied, then the first param must be the option
                option = suppliedSettings;
            }

            // Catch options

            if (option === 'update') {
                if ($this.data('perfect-scrollbar-update')) {
                    $this.data('perfect-scrollbar-update')();
                }
                return $this;
            }
            else if (option === 'destroy') {
                if ($this.data('perfect-scrollbar-destroy')) {
                    $this.data('perfect-scrollbar-destroy')();
                }
                return $this;
            }

            if ($this.data('perfect-scrollbar')) {
                // if there's already perfect-scrollbar
                return $this.data('perfect-scrollbar');
            }
            
            

            // Or generate new perfectScrollbar

            // Set class to the container
            $this.addClass('ps-container');

            var $scrollbarXRail = $("<div class='ps-scrollbar-x-rail'></div>").appendTo($this),
            $scrollbarYRail = $("<div class='ps-scrollbar-y-rail'></div>").appendTo($this),
            $scrollbarX = $("<div class='ps-scrollbar-x'></div>").appendTo($scrollbarXRail),
            $scrollbarY = $("<div class='ps-scrollbar-y'></div>").appendTo($scrollbarYRail),
            scrollbarXActive,
            scrollbarYActive,
            containerWidth,
            containerHeight,
            contentWidth,
            contentHeight,
            scrollbarXWidth,
            scrollbarXLeft,
            scrollbarXBottom = parseInt($scrollbarXRail.css('bottom'), 10),
            scrollbarYHeight,
            scrollbarYTop,
            scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10),
            eventClassName = getEventClassName();

            var updateContentScrollTop = function (currentTop, deltaY) {
                var newTop = currentTop + deltaY,
                maxTop = containerHeight - scrollbarYHeight;

                if (newTop < 0) {
                    scrollbarYTop = 0;
                }
                else if (newTop > maxTop) {
                    scrollbarYTop = maxTop;
                }
                else {
                    scrollbarYTop = newTop;
                }

                var scrollTop = parseInt(scrollbarYTop * (contentHeight - containerHeight) / (containerHeight - scrollbarYHeight), 10);
                $this.scrollTop(scrollTop);
                $scrollbarXRail.css({
                    bottom: scrollbarXBottom - scrollTop
                });
            };

            $this.updateContentScrollLeft = function (currentLeft, deltaX,_pageX) {
          
                var newLeft = currentLeft + deltaX,
                maxLeft = containerWidth - scrollbarXWidth;

                if (newLeft < 0) {
                    scrollbarXLeft = 0;
                }
                else if (newLeft > maxLeft) {
                    scrollbarXLeft = maxLeft;
                }
                else {
                    scrollbarXLeft = newLeft;
                }
                
                var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (containerWidth - scrollbarXWidth), 10);
                
                $this.scrollLeft(scrollLeft);
                //$this.scrollLeft(1366);
                $scrollbarYRail.css({
                    right: scrollbarYRight - scrollLeft
                });
                    
                  
                   
            };
            
            var getSettingsAdjustedThumbSize = function (thumbSize) {
                if (settings.minScrollbarLength) {
                    thumbSize = Math.max(thumbSize, settings.minScrollbarLength);
                }
                return thumbSize;
            };
            
            var updateScrollbarCss = function () {
                $scrollbarXRail.css({
                    left: $this.scrollLeft(), 
                    bottom: scrollbarXBottom - $this.scrollTop(), 
                    //====== following changes as per raken demands =============================
                    //bottom: 0, 
                    width: containerWidth, 
                    display: scrollbarXActive ? "inherit": "none"
                });
                $scrollbarYRail.css({
                    top: $this.scrollTop(), 
                    right: scrollbarYRight - $this.scrollLeft(), 
                    height: containerHeight, 
                    display: scrollbarYActive ? "inherit": "none"
                });
                
                $scrollbarX.css({
                    left: scrollbarXLeft, 
                    width: scrollbarXWidth
                });
                $scrollbarY.css({
                    top: scrollbarYTop, 
                    height: scrollbarYHeight
                });
        
//                //================ created by Ankit=======================
                if(!scrollbarYActive){
                    $scrollbarY.css("opacity",0);
                    $scrollbarYRail.css("opacity",0);
                }
        
                if(!scrollbarXActive){
                    $scrollbarX.css("opacity",0);
                    if(settings.isPopup)
                        $scrollbarXRail.css("opacity",0);    
                }
//        
//                if(settings.isPopup)
//                    $scrollbarYRail.css("right",0);
    
//                if(settings.slider)
//                    $scrollbarXRail.css({
//                        bottom: "40px"
//                    });
        
            //---------------- upto here -----------------------------
        
            };
            
            //============ new function for slider functionality ==========================
            
            var sliderMove = function(){
                
                var trans1 = $('#transition-1'), trans2 = $('#transition-2'), trans3 = $('#transition-3');
                var _transWidth = $('.home-social-feeds-box').width();
                
                $('ul.slider_nav > li').bind('click.anki',function(e){
                    var slide = $(this).data('slide');
                    var _movX = containerWidth/4;
                    $this.updateContentScrollLeft(0,(slide-1)*_movX);
                    
                    if(slide == 1){
                        trans1.css('left',containerWidth);
                    }
                    
                    if(slide == 2){
                        trans2.css('left',containerWidth*2)
                        trans1.css('left',containerWidth-_transWidth);
                    }
                    
                    if(slide == 3){
                        trans3.css('left',3*containerWidth);
                        trans2.css('left',containerWidth*2-_transWidth);
                    }
                    
                    e.stopPropagation();
                    e.preventDefault();
                })
                
            }
            
            //------------ slider ends----------------------

            var updateBarSizeAndPosition = function () {
          
                containerWidth = settings.includePadding ? $this.outerWidth() : $this.width();
                containerHeight = settings.includePadding ? $this.outerHeight() : $this.height();
        
                if(settings.an_MaxWidth)
                    contentWidth = settings.an_MaxWidth
                else
                    contentWidth = $this.prop('scrollWidth');
                
                contentHeight = $this.prop('scrollHeight');
                
                if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) {
                    scrollbarXActive = true;
                    scrollbarXWidth = getSettingsAdjustedThumbSize(parseInt(containerWidth * containerWidth / contentWidth, 10));
                    scrollbarXLeft = parseInt($this.scrollLeft() * (containerWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10);
                }
                else {
                    scrollbarXActive = false;
                    scrollbarXWidth = 0;
                    scrollbarXLeft = 0;
                    $this.scrollLeft(0);
                }
                
                if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {
                    scrollbarYActive = true;
                    scrollbarYHeight = getSettingsAdjustedThumbSize(parseInt(containerHeight * containerHeight / contentHeight, 10));
                    scrollbarYTop = parseInt($this.scrollTop() * (containerHeight - scrollbarYHeight) / (contentHeight - containerHeight), 10);
                }
                else {
                    scrollbarYActive = false;
                    scrollbarYHeight = 0;
                    scrollbarYTop = 0;
                    $this.scrollTop(0);
                }
                
                if (scrollbarYTop >= containerHeight - scrollbarYHeight) {
                    scrollbarYTop = containerHeight - scrollbarYHeight;
                }
                if (scrollbarXLeft >= containerWidth - scrollbarXWidth) {
                    scrollbarXLeft = containerWidth - scrollbarXWidth;
                }

                updateScrollbarCss();
            };

            var bindMouseScrollXHandler = function () {
                var currentLeft,
                currentPageX;

                $scrollbarX.bind('mousedown' + eventClassName, function (e) {
                    currentPageX = e.pageX;
                    currentLeft = $scrollbarX.position().left;
                    $scrollbarXRail.addClass('in-scrolling');
                    e.stopPropagation();
                    e.preventDefault();
                });

                if(settings.isIframe)
                    var _document = $('iframe.fancybox-iframe').contents().get(0);
                else
                    var _document = document    

                $(_document).bind('mousemove' + eventClassName, function (e) {
                    
                    if ($scrollbarXRail.hasClass('in-scrolling')) {
                        $this.updateContentScrollLeft(currentLeft, e.pageX - currentPageX,e.pageX);
                        e.stopPropagation();
                        e.preventDefault();
                    }
                });

                $(_document).bind('mouseup' + eventClassName, function (e) {
                    if ($scrollbarXRail.hasClass('in-scrolling')) {
                        $scrollbarXRail.removeClass('in-scrolling');
                    }
                });

                currentLeft =
                currentPageX = null;
            };

            var bindMouseScrollYHandler = function () {
                var currentTop,
                currentPageY;

                $scrollbarY.bind('mousedown' + eventClassName, function (e) {
                    currentPageY = e.pageY;
                    currentTop = $scrollbarY.position().top;
                    $scrollbarYRail.addClass('in-scrolling');
                    e.stopPropagation();
                    e.preventDefault();
                });

                $(document).bind('mousemove' + eventClassName, function (e) {
                    if ($scrollbarYRail.hasClass('in-scrolling')) {
                        updateContentScrollTop(currentTop, e.pageY - currentPageY);
                        e.stopPropagation();
                        e.preventDefault();
                    }
                });

                $(document).bind('mouseup' + eventClassName, function (e) {
                    if ($scrollbarYRail.hasClass('in-scrolling')) {
                        $scrollbarYRail.removeClass('in-scrolling');
                    }
                });

                currentTop =
                currentPageY = null;
            };

            // check if the default scrolling should be prevented.
            var shouldPreventDefault = function (deltaX, deltaY) {
                var scrollTop = $this.scrollTop();
                if (deltaX === 0) {
                    if (!scrollbarYActive) {
                        return false;
                    }
                    if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= contentHeight - containerHeight && deltaY < 0)) {
                        return !settings.wheelPropagation;
                    }
                }

                var scrollLeft = $this.scrollLeft();
                if (deltaY === 0) {
                    if (!scrollbarXActive) {
                        return false;
                    }
                    if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= contentWidth - containerWidth && deltaX > 0)) {
                        return !settings.wheelPropagation;
                    }
                }
                return true;
            };

            // bind handlers
            var bindMouseWheelHandler = function () {
                var shouldPrevent = false;
                $this.bind('mousewheel' + eventClassName, function (e, deprecatedDelta, deprecatedDeltaX, deprecatedDeltaY) {
                    var deltaX = e.deltaX || deprecatedDeltaX,
                    deltaY = e.deltaY || deprecatedDeltaY;

                    if (!settings.useBothWheelAxes) {
                        // deltaX will only be used for horizontal scrolling and deltaY will
                        // only be used for vertical scrolling - this is the default
                        $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
                        $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
                    } else if (scrollbarYActive && !scrollbarXActive) {
                        // only vertical scrollbar is active and useBothWheelAxes option is
                        // active, so let's scroll vertical bar using both mouse wheel axes
                        if (deltaY) {
                            $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
                        } else {
                            $this.scrollTop($this.scrollTop() + (deltaX * settings.wheelSpeed));
                        }
                    } else if (scrollbarXActive && !scrollbarYActive) {
                        // useBothWheelAxes and only horizontal bar is active, so use both
                        // wheel axes for horizontal bar
                        if (deltaX) {
                            $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
                        } else {
                            $this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed));
                        }
                    }

                    // update bar position
                    updateBarSizeAndPosition();

                    shouldPrevent = shouldPreventDefault(deltaX, deltaY);
                    if (shouldPrevent) {
                        e.preventDefault();
                    }
                });

                // fix Firefox scroll problem
                $this.bind('MozMousePixelScroll' + eventClassName, function (e) {
                    if (shouldPrevent) {
                        e.preventDefault();
                    }
                });
            };

            var bindKeyboardHandler = function () {
                var hovered = false;
                $this.bind('mouseenter' + eventClassName, function (e) {
                    hovered = true;
                });
                $this.bind('mouseleave' + eventClassName, function (e) {
                    hovered = false;
                });

                var shouldPrevent = false;
                $(document).bind('keydown' + eventClassName, function (e) {
                    if (!hovered || $(document.activeElement).is(":input,[contenteditable]")) {
                        return;
                    }

                    var deltaX = 0,
                    deltaY = 0;

                    switch (e.which) {
                        case 37: // left
                            deltaX = -3;
                            break;
                        case 38: // up
                            deltaY = 3;
                            break;
                        case 39: // right
                            deltaX = 3;
                            break;
                        case 40: // down
                            deltaY = -3;
                            break;
                        case 33: // page up
                            deltaY = 9;
                            break;
                        case 32: // space bar
                        case 34: // page down
                            deltaY = -9;
                            break;
                        case 35: // end
                            deltaY = -containerHeight;
                            break;
                        case 36: // home
                            deltaY = containerHeight;
                            break;
                        default:
                            return;
                    }

                    $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
                    $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));

                    shouldPrevent = shouldPreventDefault(deltaX, deltaY);
                    if (shouldPrevent) {
                        e.preventDefault();
                    }
                });
            };

            var bindRailClickHandler = function () {
                var stopPropagation = function (e) {
                    e.stopPropagation();
                };

                $scrollbarY.bind('click' + eventClassName, stopPropagation);
                $scrollbarYRail.bind('click' + eventClassName, function (e) {
                    var halfOfScrollbarLength = parseInt(scrollbarYHeight / 2, 10),
                    positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength,
                    maxPositionTop = containerHeight - scrollbarYHeight,
                    positionRatio = positionTop / maxPositionTop;

                    if (positionRatio < 0) {
                        positionRatio = 0;
                    } else if (positionRatio > 1) {
                        positionRatio = 1;
                    }

                    $this.scrollTop((contentHeight - containerHeight) * positionRatio);
                });

                $scrollbarX.bind('click' + eventClassName, stopPropagation);
                $scrollbarXRail.bind('click' + eventClassName, function (e) {
                    var halfOfScrollbarLength = parseInt(scrollbarXWidth / 2, 10),
                    positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength,
                    maxPositionLeft = containerWidth - scrollbarXWidth,
                    positionRatio = positionLeft / maxPositionLeft;

                    if (positionRatio < 0) {
                        positionRatio = 0;
                    } else if (positionRatio > 1) {
                        positionRatio = 1;
                    }

                    $this.scrollLeft((contentWidth - containerWidth) * positionRatio);
                });
            };

            // bind mobile touch handler
            var bindMobileTouchHandler = function () {
                var applyTouchMove = function (differenceX, differenceY) {
                    $this.scrollTop($this.scrollTop() - differenceY);
                    $this.scrollLeft($this.scrollLeft() - differenceX);

                    // update bar position
                    updateBarSizeAndPosition();
                };

                var startCoords = {},
                startTime = 0,
                speed = {},
                breakingProcess = null,
                inGlobalTouch = false;

                $(window).bind("touchstart" + eventClassName, function (e) {
                    inGlobalTouch = true;
                });
                $(window).bind("touchend" + eventClassName, function (e) {
                    inGlobalTouch = false;
                });

                $this.bind("touchstart" + eventClassName, function (e) {
                    var touch = e.originalEvent.targetTouches[0];

                    startCoords.pageX = touch.pageX;
                    startCoords.pageY = touch.pageY;

                    startTime = (new Date()).getTime();

                    if (breakingProcess !== null) {
                        clearInterval(breakingProcess);
                    }

                    e.stopPropagation();
                });
                $this.bind("touchmove" + eventClassName, function (e) {
                    if (!inGlobalTouch && e.originalEvent.targetTouches.length === 1) {
                        var touch = e.originalEvent.targetTouches[0];

                        var currentCoords = {};
                        currentCoords.pageX = touch.pageX;
                        currentCoords.pageY = touch.pageY;

                        var differenceX = currentCoords.pageX - startCoords.pageX,
                        differenceY = currentCoords.pageY - startCoords.pageY;

                        applyTouchMove(differenceX, differenceY);
                        startCoords = currentCoords;

                        var currentTime = (new Date()).getTime();

                        var timeGap = currentTime - startTime;
                        if (timeGap > 0) {
                            speed.x = differenceX / timeGap;
                            speed.y = differenceY / timeGap;
                            startTime = currentTime;
                        }

                        e.preventDefault();
                    }
                });
                $this.bind("touchend" + eventClassName, function (e) {
                    clearInterval(breakingProcess);
                    breakingProcess = setInterval(function () {
                        if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
                            clearInterval(breakingProcess);
                            return;
                        }

                        applyTouchMove(speed.x * 30, speed.y * 30);

                        speed.x *= 0.8;
                        speed.y *= 0.8;
                    }, 10);
                });
            };

            var bindScrollHandler = function () {
                $this.bind('scroll' + eventClassName, function (e) {
                    updateBarSizeAndPosition();
                });
            };

            var destroy = function () {
                $this.unbind(eventClassName);
                $(window).unbind(eventClassName);
                $(document).unbind(eventClassName);
                $this.data('perfect-scrollbar', null);
                $this.data('perfect-scrollbar-update', null);
                $this.data('perfect-scrollbar-destroy', null);
                $scrollbarX.remove();
                $scrollbarY.remove();
                $scrollbarXRail.remove();
                $scrollbarYRail.remove();

                // clean all variables
                $scrollbarX =
                $scrollbarY =
                containerWidth =
                containerHeight =
                contentWidth =
                contentHeight =
                scrollbarXWidth =
                scrollbarXLeft =
                scrollbarXBottom =
                scrollbarYHeight =
                scrollbarYTop =
                scrollbarYRight = null;
            };

            var ieSupport = function (version) {
                $this.addClass('ie').addClass('ie' + version);

                var bindHoverHandlers = function () {
                    var mouseenter = function () {
                        $(this).addClass('hover');
                    };
                    var mouseleave = function () {
                        $(this).removeClass('hover');
                    };
                    $this.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
                    $scrollbarXRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
                    $scrollbarYRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
                    $scrollbarX.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
                    $scrollbarY.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
                };

                var fixIe6ScrollbarPosition = function () {
                    updateScrollbarCss = function () {
                        $scrollbarX.css({
                            left: scrollbarXLeft + $this.scrollLeft(), 
                            bottom: scrollbarXBottom, 
                            width: scrollbarXWidth
                        });
                        $scrollbarY.css({
                            top: scrollbarYTop + $this.scrollTop(), 
                            right: scrollbarYRight, 
                            height: scrollbarYHeight
                        });
                        $scrollbarX.hide().show();
                        $scrollbarY.hide().show();
                    };
                };

                if (version === 6) {
                    bindHoverHandlers();
                    fixIe6ScrollbarPosition();
                }
            };

            var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);

            var initialize = function () {
                var ieMatch = navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);
                if (ieMatch && ieMatch[1] === 'msie') {
                    // must be executed at first, because 'ieSupport' may addClass to the container
                    ieSupport(parseInt(ieMatch[2], 10));
                }

                updateBarSizeAndPosition();
                bindScrollHandler();
                bindMouseScrollXHandler();
                bindMouseScrollYHandler();
                bindRailClickHandler();
                sliderMove();
                if (supportsTouch) {
                    bindMobileTouchHandler();
                }
                if ($this.mousewheel) {
                    bindMouseWheelHandler();
                }
                if (settings.useKeyboard) {
                    bindKeyboardHandler();
                }
                $this.data('perfect-scrollbar', $this);
                $this.data('perfect-scrollbar-update', updateBarSizeAndPosition);
                $this.data('perfect-scrollbar-destroy', destroy);
            };

            // initialize
            initialize();

            return $this;
        });
    };
}));
